package cn.virens.common.mybatis.dynamic_table.proxy;

import io.mybatis.provider.EntityTable;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.InvocationHandlerAdapter;
import net.bytebuddy.matcher.ElementMatchers;
import org.dromara.hutool.core.classloader.ClassLoaderUtil;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class DynamicTableNameProxyBuddy extends DynamicTableNameProxy implements InvocationHandler {
    private final EntityTable target;

    public static EntityTable buildProxy(EntityTable target) throws Exception {
        return new ByteBuddy().subclass(EntityTable.class).method(ElementMatchers.any())//
                .intercept(InvocationHandlerAdapter.of(new DynamicTableNameProxyBuddy(target)))//
                .make().load(ClassLoaderUtil.getClassLoader())//
                .getLoaded().getConstructor(Class.class)//
                .newInstance(target.entityClass());
    }

    public DynamicTableNameProxyBuddy(EntityTable target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method != null && isMethod(method, "tableName", String.class)) {
            return generateDynamicTableName(target.tableName());
        }

        return method.invoke(target, args);
    }

}
